/**
 * @author Administrator
 */
/**
 * @author Administrator
 *
 */
package com.sgy;


import com.ice.jni.registry.RegistryException;
import com.sgy.config.SystemProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.swing.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import java.util.concurrent.TimeUnit;

/**
 * 1.创建一个ServerSocket对象；
 * 2.调用ServerSocket对象的accept方法，等待连接，连接成功会返回一个Socket对象，否则一直阻塞等待；
 * 3.从Socket对象中获取InputStream和OutputStream字节流，这两个流分别对应request请求和response响应；
 * 4.处理请求：读取InputStream字节流信息，转成字符串形式，并解析，这里的解析比较简单，仅仅获取uri(统一资源标识符)信息;
 * 5.处理响应：根据解析出来的uri信息，从WEB_ROOT目录中寻找请求的资源资源文件, 读取资源文件，并将其写入到OutputStream字节流中；
 * 6.关闭Socket对象；
 * 7.转到步骤2，继续等待连接请求；
 */
public class Client {
    private static final Logger log = LoggerFactory.getLogger(Client.class);
    private final SystemProperties systemProperties;

    static final int listenPort = 8788;

    static final String listenIP = "127.0.0.1";

    static final String foreignIP = "*.*.*.*";

    private final ThreadPoolTaskExecutor threadPoolExecutor;

    public Client(SystemProperties systemProperties, ThreadPoolTaskExecutor threadPoolExecutor) {
        doShutDownWork();
        this.systemProperties = systemProperties;
        this.threadPoolExecutor = threadPoolExecutor;
    }

    private void doShutDownWork() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            Proxy proxy = new Proxy();
            try {
                // 设置代理服务器
                proxy.disableProxy();
            } catch (RegistryException ex) {
                ex.printStackTrace();
            }
        }));
    }

    public void start() {
        new Thread(() -> {
            try {
                // 设置代理服务器
                Proxy proxy = new Proxy();
                // IE代理服务器
                proxy.changeProxy(listenIP, listenPort);
            } catch (Exception ex) {
                log.error("PC Proxy Server Setting Error:" + ex.getMessage());
            }

            try {
                // 开启本地代理服务器
                // 等待连接请求
                SystemProperties.Server server = systemProperties.getServer();
                this.await(server);
            } catch (Exception ex) {
                log.error("Proxy Client Error:" + ex.getMessage());
            }
        }).start();
    }


    private static void initLookAndFeel() {
        String lookAndFeel = null;

        lookAndFeel = UIManager.getSystemLookAndFeelClassName();

        try {
            UIManager.setLookAndFeel(lookAndFeel);
        } catch (ClassNotFoundException e) {
            System.err.println("Couldn't find class for specified look and feel:"
                    + lookAndFeel);
            System.err.println("Did you include the L&F library in the class path?");
            System.err.println("Using the default look and feel.");
        } catch (UnsupportedLookAndFeelException e) {
            System.err.println("Can't use the specified look and feel ("
                    + lookAndFeel
                    + ") on this platform.");
            System.err.println("Using the default look and feel.");
        } catch (Exception e) {
            System.err.println("Couldn't get specified look and feel ("
                    + lookAndFeel
                    + "), for some reason.");
            System.err.println("Using the default look and feel.");
            e.printStackTrace();
        }
    }

    public void await(SystemProperties.Server server) {
        String serverIP = server.getHost();
        String serverPort = String.valueOf(server.getPort());
        log.info("serverIp: {}, serverPort: {}, listenPort: {}", serverIP, serverPort, listenPort);
        while (true) {
            // 创建一个ServerSocket对象
            try (ServerSocket serverSocket = new ServerSocket(listenPort, 1, InetAddress.getByName(listenIP))) {
                // 循环等待一个请求
                for (;;) {
                    Socket socket;
                    try {
                        socket = serverSocket.accept();
                        socket.setKeepAlive(true);

                        // 加入任务列表，等待处理
                        ClientProxy cp = new ClientProxy(socket, serverIP, serverPort);
                        threadPoolExecutor.execute(cp);
                    } catch (Exception e) {
                        log.error("error: ", e);
                        TimeUnit.SECONDS.sleep(5);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
}
